/*
 Funções responsáveis por criar, inserir e retirar da pilha de method_frames
 Verificar se a pilha está vazia
 */

#include "stack.h"

extern stack *framestack;
extern class_list *methodarea;
extern class_file *mainclass;

stack *new_stack(void) {
	stack *new = (stack *) calloc(1, sizeof(stack));
	if (!new) {
		printf(
				"Pilha_nova: nao foi possivel alocar espaco para uma nova pilha. ");
		exit(1);
	}

	return new;
}

int empty_stack(stack *p) {
	if (!p) {
		printf("Pilha_vazia: parametro nulo");
		exit(1);
	}
	return p->top == NULL;
}

void push_stack(stack *p, method_frame *frame) {
	frame_stack *new_frame;
	if (!p) {
		printf("Pilha inexistente");
		exit(1);
	}

	if (empty_stack(p) == 1) {
		new_frame = (frame_stack *) calloc(1, sizeof(frame_stack));
		new_frame->frame = frame;
		new_frame->next = NULL;
	} else {
		/* Cria um novo elemento e coloca ele no topo da pilha */
		new_frame = (frame_stack *) calloc(1, sizeof(frame_stack));
		new_frame->frame = frame;
		new_frame->next = p->top;
	}

	p->top = new_frame;
}

void pop_stack(stack *p) {
	frame_stack *new_top;
	if (!p) {
		printf("Nao existe pilha");
		exit(1);
	}
	/* Se a pilha eh vazia */
	if (p->top == NULL) {
		printf("Pilha vazia!!!!");
		exit(1);
	}

	/* Se tem algo na pilha */
	new_top = p->top->next;
	free(p->top);
	p->top = new_top;
}

void free_stack(stack *p) {
	frame_stack *e;
	e = (frame_stack *) malloc(sizeof(frame_stack));
	if (!p) {
		printf("Nao existe pilha");
		exit(1);
	}
	while ((e->next) != NULL) {
		e = p->top->next;
		free(p->top);
		p->top = e;
	}
	free(p);
}
